home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * An SGI 4D driver using Open GL. *
- * *
- * Written by: Gershon Elber Ver 0.1, October 1994. *
- *****************************************************************************/
-
- #ifdef __hpux
- typedef char *caddr_t; /* Awful kludge. Let me know of a better way. */
- #endif /* __hpux */
-
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <X11/cursorfont.h>
- #include <X11/Xresource.h>
-
- #include <GL/glx.h>
- #include <GL/gl.h>
- #include <gl/glws.h>
- #include <unistd.h>
-
- #include <math.h>
- #include "irit_sm.h"
- #include "genmat.h"
- #include "iritprsr.h"
- #include "allocate.h"
- #include "attribut.h"
- #include "iritgrap.h"
- #include "x11drvs.h"
-
- typedef enum {
- GLXcolorIndexSingleBuffer,
- GLXcolorIndexDoubleBuffer,
- GLXrgbSingleBuffer,
- GLXrgbDoubleBuffer
- } GLXWindowType;
-
- static Colormap CMap;
-
- static short Colors[IG_MAX_COLOR + 1][3] =
- {
- { 0, 0, 0 }, /* 0. BLACK */
- { 0, 0, 170 }, /* 1. BLUE */
- { 0, 170, 0 }, /* 2. GREEN */
- { 0, 170, 170 }, /* 3. CYAN */
- { 170, 0, 0 }, /* 4. RED */
- { 170, 0, 170 }, /* 5. MAGENTA */
- { 170, 170, 0 }, /* 6. BROWN */
- { 170, 170, 170 }, /* 7. LIGHTGREY */
- { 85, 85, 85 }, /* 8. DARKGRAY */
- { 85, 85, 255 }, /* 9. LIGHTBLUE */
- { 85, 255, 85 }, /* 10. LIGHTGREEN */
- { 85, 255, 255 }, /* 11. LIGHTCYAN */
- { 255, 85, 85 }, /* 12. LIGHTRED */
- { 255, 85, 255 }, /* 13. LIGHTMAGENTA */
- { 255, 255, 85 }, /* 14. YELLOW */
- { 255, 255, 255 } /* 15. WHITE */
- };
-
- static void SetColorRGB(int Color[3]);
- static void SetColorIndex(int c);
- static void SetEntry(GLXconfig* ptr, int b, int m, int a);
- static Window GLXCreateWindow(Display *XDisplay,
- Window Parent,
- int x,
- int y,
- int w,
- int h,
- int BorderWidth,
- GLXWindowType Type);
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Draw a single Point/Vector object using current modes and transformations. M
- * *
- * PARAMETERS: M
- * PObj: A point/vector object to draw. M
- * *
- * RETURN VALUE: M
- * void M
- * *
- * KEYWORDS: M
- * IGDrawPtVec M
- *****************************************************************************/
- void IGDrawPtVec(IPObjectStruct *PObj)
- {
- int i;
- PointType Ends[6], Zero;
- RealType
- *Pt = PObj -> U.Pt;
-
- for (i = 0; i < 6; i++)
- PT_COPY(Ends[i], Pt);
-
- Ends[0][0] -= IG_POINT_WIDTH;
- Ends[1][0] += IG_POINT_WIDTH;
- Ends[2][1] -= IG_POINT_WIDTH;
- Ends[3][1] += IG_POINT_WIDTH;
- Ends[4][2] -= IG_POINT_WIDTH;
- Ends[5][2] += IG_POINT_WIDTH;
-
- for (i = 0; i < 6; i += 2) {
- glBegin(GL_LINES);
- glVertex3dv(Ends[i]);
- glVertex3dv(Ends[i+1]);
- glEnd();
- }
-
- if (IP_IS_VEC_OBJ(PObj)) {
- glBegin(GL_LINES);
- glVertex3dv(Pt);
- Zero[0] = Zero[1] = Zero[2] = 0.0;
- glVertex3dv(Zero);
- glEnd();
- }
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Draw a single Poly object using current modes and transformations. M
- * *
- * PARAMETERS: M
- * PObj: A poly object to draw. M
- * *
- * RETURN VALUE: M
- * void M
- * *
- * KEYWORDS: M
- * IGDrawPoly M
- *****************************************************************************/
- void IGDrawPoly(IPObjectStruct *PObj)
- {
- IPVertexStruct *V;
- IPPolygonStruct
- *Pl = PObj -> U.Pl;
-
- if (IP_IS_POLYLINE_OBJ(PObj)) {
- for (; Pl != NULL; Pl = Pl -> Pnext) {
- glBegin(GL_LINE_STRIP);
- for (V = Pl -> PVertex; V != NULL; V = V -> Pnext)
- glVertex3dv(V -> Coord);
- glEnd();
- }
- }
- else if (IP_IS_POINTLIST_OBJ(PObj)) {
- for (; Pl != NULL; Pl = Pl -> Pnext) {
- for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
- int i;
- PointType Ends[6];
- RealType
- *Pt = V -> Coord;
-
- for (i = 0; i < 6; i++)
- PT_COPY(Ends[i], Pt);
-
- Ends[0][0] -= IG_POINT_WIDTH;
- Ends[1][0] += IG_POINT_WIDTH;
- Ends[2][1] -= IG_POINT_WIDTH;
- Ends[3][1] += IG_POINT_WIDTH;
- Ends[4][2] -= IG_POINT_WIDTH;
- Ends[5][2] += IG_POINT_WIDTH;
-
- for (i = 0; i < 6; i += 2) {
- glBegin(GL_LINES);
- glVertex3dv(Ends[i]);
- glVertex3dv(Ends[i+1]);
- glEnd();
- }
- }
- }
- }
- else if (IP_IS_POLYGON_OBJ(PObj)) {
- int i, j,
- NumOfVertices;
- PointType PNormal, VNormal;
-
- for (; Pl != NULL; Pl = Pl -> Pnext) {
- if (IGGlblDrawPNormal) {
- NumOfVertices = 0;
- PNormal[0] = PNormal[1] = PNormal[2] = 0.0;
- }
-
- if (IGGlblDrawSolid) {
- glBegin(GL_POLYGON);
- for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
- glNormal3dv(V -> Normal);
- glVertex3dv(V -> Coord);
-
- if (IGGlblDrawPNormal) {
- for (j = 0; j < 3; j++)
- PNormal[j] += V -> Coord[j];
- NumOfVertices++;
- }
- }
- glEnd();
- }
- else {
- glBegin(GL_LINE_STRIP);
- for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
- glVertex3dv(V -> Coord);
- if (IP_IS_INTERNAL_VRTX(V) && !IGGlblDrawInternal) {
- glEnd();
- glBegin(GL_LINE_STRIP);
- }
-
- if (IGGlblDrawPNormal) {
- for (j = 0; j < 3; j++)
- PNormal[j] += V -> Coord[j];
- NumOfVertices++;
- }
- }
- glVertex3dv(Pl -> PVertex -> Coord);
- glEnd();
- }
-
- if (IGGlblDrawPNormal && IP_HAS_PLANE_POLY(Pl)) {
- glBegin(GL_LINES);
- for (i = 0; i < 3; i++)
- PNormal[i] /= NumOfVertices;
- glVertex3dv(PNormal);
- for (i = 0; i < 3; i++)
- PNormal[i] += Pl -> Plane[i] * IGGlblNormalLen;
- glVertex3dv(PNormal);
- glEnd();
- }
-
- if (IGGlblDrawVNormal) {
- for (V = Pl -> PVertex; V != NULL; V = V -> Pnext) {
- if (IP_HAS_NORMAL_VRTX(V)) {
- for (j = 0; j < 3; j++)
- VNormal[j] = V -> Coord[j] +
- V -> Normal[j] * IGGlblNormalLen;
- glBegin(GL_LINES);
- glVertex3dv(V ->Coord);
- glVertex3dv(VNormal);
- glEnd();
- }
- }
- }
- }
- }
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Sets the color of an object according to its color/rgb attributes. M
- * If object has an RGB attribute it will be used. Otherwise, if the object M
- * has a COLOR attribute it will use. Otherwise, WHITE will be used. M
- * *
- * PARAMETERS: M
- * PObj: To set the drawing color to its color. M
- * *
- * RETURN VALUE: M
- * void M
- * *
- * KEYWORDS: M
- * IGSetColorObj M
- *****************************************************************************/
- void IGSetColorObj(IPObjectStruct *PObj)
- {
- int c, Color[3];
-
- if (AttrGetObjectRGBColor(PObj, &Color[0], &Color[1], &Color[2])) {
- SetColorRGB(Color);
- }
- else if ((c = AttrGetObjectColor(PObj)) != IP_ATTR_NO_COLOR) {
- SetColorIndex(c);
- }
- else {
- /* Use white as default color: */
- SetColorIndex(IG_IRIT_WHITE);
- }
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Sets the line width to draw the given object, in pixels. M
- * *
- * PARAMETERS: M
- * Width: In pixels of lines to draw with. M
- * *
- * RETURN VALUE: M
- * void M
- * *
- * KEYWORDS: M
- * IGSetWidthObj M
- *****************************************************************************/
- void IGSetWidthObj(int Width)
- {
- glLineWidth(Width);
- }
-
- /*****************************************************************************
- * DESCRIPTION: *
- * Sets the color according to the given color index. *
- * *
- * PARAMETERS: *
- * color: Index of color to use. Must be between 0 and IG_MAX_COLOR. *
- * *
- * RETURN VALUE: *
- * void *
- *****************************************************************************/
- static void SetColorIndex(int color)
- {
- int Color[3];
-
- if (color < 0 || color > IG_MAX_COLOR)
- color = IG_IRIT_WHITE;
-
- Color[0] = Colors[color][0];
- Color[1] = Colors[color][1];
- Color[2] = Colors[color][2];
-
- SetColorRGB(Color);
- }
-
- /*****************************************************************************
- * DESCRIPTION: *
- * Sets the color according to the given RGB values. *
- * *
- * PARAMETERS: *
- * Color: An RGB vector of integer values between 0 and 255. *
- * *
- * RETURN VALUE: *
- * void *
- *****************************************************************************/
- static void SetColorRGB(int Color[3])
- {
- int i;
-
- if (IGGlblDrawSolid) {
- GLfloat MatAmbient[4], MatDiffuse[4], MatSpecular[4];
- static GLfloat
- MatShininess[] = { 15.0 };
-
- for (i = 0; i < 3; i++) {
- MatAmbient[i] = 0.2 * Color[0] / 255.0;
- MatDiffuse[i] = 0.4 * Color[i] / 255.0;
- MatSpecular[i] = Color[i] / 255.0;
- }
- MatAmbient[3] = MatDiffuse[3] = MatSpecular[3] = 1.0;
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, MatAmbient);
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MatDiffuse);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, MatSpecular);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, MatShininess);
- }
- else
- glColor3f(Color[0] / 255.0, Color[1] / 255.0, Color[2] / 255.0);
-
- if (IGGlblDepthCue) {
- GLfloat fogColor[4];
-
- for (i = 0; i < 3; i++)
- fogColor[i] = (float) IGGlblBackGroundColor[i] / 255.0;
- fogColor[3] = (float) 1.0;
-
- glEnable(GL_FOG);
- glFogi(GL_FOG_MODE, GL_LINEAR);
- glHint(GL_FOG_HINT, GL_NICEST);
- glFogf(GL_FOG_START, (float) IGGlblZMinClip);
- glFogf(GL_FOG_END, (float) IGGlblZMaxClip);
- glFogfv(GL_FOG_COLOR, fogColor);
- }
- else
- glDisable(GL_FOG);
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * This routine (along with SetEntry) was copied from the GLX examples of SGI M
- * under 4DGifts. Why is it so difficult to open a window!? M
- * *
- * PARAMETERS: M
- * XDisplay: Display M
- * Parent: Parent window. M
- * x, y: Location. M
- * w, h: Size. M
- * BorderWidth: Border width. M
- * Type: Type of window requested. M
- * *
- * RETURN VALUE: M
- * Window: Created window, NULL if failed. M
- * *
- * KEYWORDS: M
- * GLXCreateWindow M
- *****************************************************************************/
- static void SetEntry(GLXconfig* ptr, int b, int m, int a)
- {
- ptr->buffer = b;
- ptr->mode = m;
- ptr->arg = a;
- }
-
- static Window GLXCreateWindow(Display *XDisplay,
- Window Parent,
- int x,
- int y,
- int w,
- int h,
- int BorderWidth,
- GLXWindowType Type)
- {
- GLXconfig params[50];
- GLXconfig *next;
- GLXconfig *retconfig;
- XVisualInfo *vis;
- XVisualInfo template;
- XColor white;
- XSetWindowAttributes cwa;
- XWindowAttributes pwa;
- int i, nret;
- Window win;
- static char
- *TypeToName[] = {
- "color index single buffer",
- "color index double buffer",
- "rgb single buffer",
- "rgb double buffer",
- };
-
- CMap = DefaultColormap(XDisplay, DefaultScreen(XDisplay));
-
- /*
- * This builds an array in "params" that describes for GLXgetconfig(3G)
- * the type of GL drawing that will be done.
- */
- next = params;
- switch (Type) {
- case GLXcolorIndexSingleBuffer:
- SetEntry(next++, GLX_NORMAL, GLX_RGB, FALSE);
- SetEntry(next++, GLX_NORMAL, GLX_DOUBLE, FALSE);
- break;
- case GLXcolorIndexDoubleBuffer:
- SetEntry(next++, GLX_NORMAL, GLX_RGB, FALSE);
- SetEntry(next++, GLX_NORMAL, GLX_DOUBLE, TRUE);
- break;
- case GLXrgbSingleBuffer:
- SetEntry(next++, GLX_NORMAL, GLX_RGB, TRUE);
- SetEntry(next++, GLX_NORMAL, GLX_DOUBLE, FALSE);
- break;
- case GLXrgbDoubleBuffer:
- SetEntry(next++, GLX_NORMAL, GLX_RGB, TRUE);
- SetEntry(next++, GLX_NORMAL, GLX_DOUBLE, TRUE);
- break;
- }
- SetEntry(next, 0, 0, 0); /* The input to GLXgetconfig is null terminated */
-
- /*
- * Get configuration data for a window based on above parameters
- * First we have to find out which screen the parent window is on,
- * then we can call GXLgetconfig()
- */
- XGetWindowAttributes(XDisplay, Parent, &pwa);
- retconfig = GLXgetconfig(XDisplay, XScreenNumberOfScreen(pwa.screen),
- params);
- if (retconfig == 0) {
- printf("Sorry, can't support %s type of windows\n", TypeToName[Type]);
- exit(-1);
- }
- /*
- * The GL sets its own X error handlers, which aren't as informative
- * when errors happen. Calling XSetErrorHandler(0) here will
- * reset back to the default Xlib version.
- */
- XSetErrorHandler(0);
-
- /*
- * Scan through config info, pulling info needed to create a window
- * that supports the rendering mode.
- */
- for (next = retconfig; next->buffer; next++) {
- unsigned long buffer = next->buffer;
- unsigned long mode = next->mode;
- unsigned long value = next->arg;
- switch (mode) {
- case GLX_COLORMAP:
- if (buffer == GLX_NORMAL) {
- CMap = value;
- }
- break;
- case GLX_VISUAL:
- if (buffer == GLX_NORMAL) {
- template.visualid = value;
- template.screen = DefaultScreen(XDisplay);
- vis = XGetVisualInfo(XDisplay, VisualScreenMask | VisualIDMask,
- &template, &nret);
- }
- break;
- }
- }
-
- /*
- * Create the window
- */
- cwa.colormap = CMap;
- cwa.border_pixel = 0; /* Even if we don't use it, it must be something */
- win = XCreateWindow(XDisplay, Parent, x, y, w, h,
- BorderWidth, vis->depth, InputOutput, vis->visual,
- CWColormap|CWBorderPixel, &cwa);
-
- /*
- * Rescan configuration info and find window slot that getconfig
- * provided. Fill it in with the window we just created.
- */
- for (next = retconfig; next->buffer; next++) {
- if ((next->buffer == GLX_NORMAL) && (next->mode == GLX_WINDOW)) {
- next->arg = win;
- break;
- }
- }
-
- /*
- * Now "retconfig" contains all the information the GL needs to
- * configure the window and its own internal state.
- */
- i = GLXlink(XDisplay, retconfig);
- if (i < 0) {
- printf("GLXlink returned %d\n", i);
- exit(-1);
- }
-
- return win;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Sets up a view window. M
- * *
- * PARAMETERS: M
- * argc, argv: Command line, M
- * *
- * RETURN VALUE: M
- * void M
- * *
- * KEYWORDS: M
- * SetViewWindow M
- *****************************************************************************/
- void SetViewWindow(int argc, char **argv)
- {
- static int
- UpdateLightPos = FALSE;
- static GLfloat
- Light0Position[4] = { 1.0, 2.0, 10.0, 0.0 },
- Light1Position[4] = { -5.0, -1.0, -10.0, 0.0 },
- LightAmbient[] = { 1.0, 1.0, 1.0, 1.0 },
- LightDiffuse[] = { 1.0, 1.0, 1.0, 1.0 },
- LightSpecular[] = { 1.0, 1.0, 1.0, 1.0 },
- LModelAmbient[] = { 0.2, 0.2, 0.2, 1.0 };
- Cursor XCursor;
-
- ViewWndw = GLXCreateWindow(XDisplay, XRoot,
- ViewPosX, ViewPosY,
- ViewWidth, ViewHeight,
- 0, GLXrgbDoubleBuffer);
-
- /* Set our own cursor: */
- XCursor = XCreateFontCursor(XDisplay, XC_iron_cross);
- XDefineCursor(XDisplay, ViewWndw, XCursor);
- if (ViewCursorColor != NULL)
- XRecolorCursor(XDisplay, XCursor, ViewCursorColor, &BlackColor);
-
- XSelectInput(XDisplay, ViewWndw, ExposureMask | ButtonPressMask);
-
- XMapWindow(XDisplay, ViewWndw);
-
- if (!UpdateLightPos) {
- int i;
-
- for (i = 0; i < 4; i++)
- Light0Position[i] = IGGlblLightSrcPos[i];
- UpdateLightPos = TRUE;
- }
-
- glXMakeCurrent(XDisplay, None, NULL);
-
- glLightfv(GL_LIGHT0, GL_POSITION, Light0Position);
- glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
- glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpecular);
- glLightfv(GL_LIGHT1, GL_POSITION, Light1Position);
- glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);
- glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);
- glLightfv(GL_LIGHT1, GL_SPECULAR, LightSpecular);
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT, LModelAmbient);
-
- glDepthFunc(GL_GREATER);
- glClearDepth(0.0);
- }
-
- /*****************************************************************************
- * DESCRIPTION: *
- * Redraw the view window. *
- * *
- * PARAMETERS: *
- * None *
- * *
- * RETURN VALUE: *
- * void *
- *****************************************************************************/
- void RedrawViewWindow(void)
- {
- IPObjectStruct *PObj;
- GLdouble CrntView[16];
- int i, j, k;
-
- glDrawBuffer(IGGlblDoDoubleBuffer ? GL_BACK : GL_FRONT);
-
- /* Clear viewing area. */
- glClear(GL_COLOR_BUFFER_BIT |
- (IGGlblDrawSolid ? GL_DEPTH_BUFFER_BIT : 0));
-
- /* activate zbuffer only if we are in solid drawing mode. */
- if (IGGlblDrawSolid) {
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
- glEnable(GL_LIGHT1);
- glEnable(GL_DEPTH_TEST);
- glDisable(GL_CULL_FACE);
- glClear(GL_DEPTH_BUFFER_BIT);
- }
- else {
- glDisable(GL_LIGHTING);
- glDisable(GL_LIGHT0);
- glDisable(GL_LIGHT1);
- glDisable(GL_DEPTH_TEST);
- }
-
- if (IGGlblViewMode == IG_VIEW_PERSPECTIVE) {
- for (i = 0; i < 4; i++)
- for (j = 0; j < 4; j++) {
- CrntView[i * 4 + j] = 0;
- for (k = 0; k < 4; k++)
- CrntView[i * 4 + j] += IritPrsrViewMat[i][k] *
- IritPrsrPrspMat[k][j];
- }
- }
- else {
- for (i = 0; i < 4; i++)
- for (j = 0; j < 4; j++)
- CrntView[i * 4 + j] = IritPrsrViewMat[i][j];
- }
-
- glLoadMatrixd(CrntView);
- glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
-
- for (PObj = IGGlblDisplayList; PObj != NULL; PObj = PObj -> Pnext)
- IGDrawObject(PObj);
- glFlush();
-
- if (IGGlblDoDoubleBuffer)
- glXSwapBuffers(XDisplay, ViewWndw);
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * To handle internal events. Should not block. M
- * *
- * PARAMETERS: M
- * None M
- * *
- * RETURN VALUE: M
- * void M
- *****************************************************************************/
- void IGHandleInternalEvents(void)
- {
- }
-